package com.mercury.ec.framework.air.core.client.impl.sunstn.execute;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.mercury.ec.framework.air.core.client.impl.sunstn.dto.SunstnCommonReqDTO;
import com.mercury.ec.framework.air.core.client.impl.sunstn.dto.SunstnCommonRespDTO;
import com.mercury.ec.framework.common.exception.ServiceException;
import com.mercury.ec.module.basic.enums.BasicBizScopeTypeEnum;
import lombok.extern.slf4j.Slf4j;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Map;

import static com.mercury.ec.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.mercury.ec.module.air.enums.ErrorCodeConstants.AIR_SUNSTN_API_CALL_EXCEPTION;

/**
 * sunstn 请求客户端
 *
 * @author hesx
 */
@Slf4j
public class DefaultSunstnAirExecute implements SunstnAirExecute {

    @Override
    public <T> SunstnCommonRespDTO<T> execute(String url, String uid, SunstnCommonReqDTO request, Class<T> clazz) throws ServiceException {
        SunstnCommonRespDTO res = new SunstnCommonRespDTO();
        Map<String, Object> paramMap = BeanUtil.beanToMap(request, false, true);
        paramMap.remove("scopeType"); // 移除自定义参数
        paramMap.put("uid", uid);
        String params = HttpUtil.toParams(paramMap);
        try {
            String result = HttpUtil.get(url + "?" + params, Charset.forName("GB18030"));
//            String result = HttpUtil.get(url + "?" + params, Charset.forName("UTF-8"));
//            String result = HttpUtil.get(url + "?" + params);
            log.info("SUNSTN接口地址【{}】指令【{}】请求【{}】原始响应【{}】", url, request.getCmd(), params, result);
            if (StrUtil.isNotBlank(result)) {
                if (!StrUtil.startWith(result, "<")) {
                    // 非xml则为报错
                    throw new ServiceException(AIR_SUNSTN_API_CALL_EXCEPTION.getCode(), result);
                }
                JAXBContext context = JAXBContext.newInstance(clazz);
                Unmarshaller unmarshaller = context.createUnmarshaller();
                Object object;
                if (BasicBizScopeTypeEnum.isDomestic(request.getScopeType())) {
//                    object = unmarshaller.unmarshal(new ByteArrayInputStream(result.getBytes("GB18030")));
                    object = unmarshaller.unmarshal(new InputStreamReader(new ByteArrayInputStream(result.getBytes("GB18030")), "GB18030"));
                } else {
//                    object = unmarshaller.unmarshal(new ByteArrayInputStream(result.getBytes("UTF-8")));
                    object = unmarshaller.unmarshal(new InputStreamReader(new ByteArrayInputStream(result.getBytes("UTF-8")), "UTF-8"));
                }
                // 参数转换
                res.setData(object);
                log.info("SUNSTN接口地址【{}】指令【{}】请求【{}】标准响应【{}】", url, request.getCmd(), params, JSONUtil.toJsonPrettyStr(res));
                res.setXml(result.replaceAll("\\r", "").replaceAll("\\n", ""));
            }
        } catch (Exception e) {
            log.error("SUNSTN接口【{}】指令【{}】请求【{}】调用异常", url, request.getCmd(), params, e);
            throw exception(AIR_SUNSTN_API_CALL_EXCEPTION, request.getCmd(), e.getMessage());
        }
        return res;
    }
}
